# comment line

echo 
echo 普通变量, =两边不可以有空格
normal_var="normal variable"
echo 使用变量
echo normal_var=${normal_var}

# 局部变量, 只能在函数中用
# local local_var="local variable"

echo 
echo 环境变量
echo PATH=$PATH

echo
echo 只读变量
readonly readonly_var="readonly variable"
echo 无法修改只读变量
readonly_var="change readonly variable"
echo readonly_var=$readonly_var

echo
echo 删除变量
unset normal_var
echo normal_var=${normal_var}
echo 无法删除只读变量
unset readonly_var
echo readonly_var=${readonly_var}

echo
echo 单引号变量中无变量，不转义
single_quotation_var='readonly_var:\t${readonly_var}'
echo single_quotation_var=${single_quotation_var}
echo 双引号中可以用变量，有转义
double_quotation_var="readonly_var:\t${readonly_var}"
echo double_quotation_var=${double_quotation_var}
echo 字符串直接拼接，不用+, 中间不能有空格
string_var="concatenate "some" strings"
echo string_var=${string_var}
echo 获取字符串长度
echo \#string_var=${#string_var}
echo 提取字符串
echo string_var[1:5]=${string_var:1:4}
echo string_var[:5]=${string_var::5}

echo
echo 数组，bash中仅支持一维数组
echo 数组定义
string_array=(one two three four)
echo 输出数组
echo string_array=${string_array[@]}
echo 数组定义2
array2[0]=0
array2[8]=8
array2[18]=18
echo array2=${array2[@]}
echo 获取数组中的元素
echo array2[0]=${array2[0]}
echo array2[1]=${array2[1]}
echo array2[8]=${array2[8]}
echo array2[9]=${array2[9]}
echo 获取数组中元素个数
echo \#array2=${#array2[@]}
echo 获取单个元素长度
echo \#array2[18]=${#array2[18]}

echo 
echo 获取参数
echo \$0永远表示被执行的文件名
echo filename=$0
echo \$n表示传入的第n个参数
echo param1=$1
echo \$\#表示参数个数（不包括\$0）
echo There are $# params
echo \$\*用空格分隔所有参数的字符串
echo All params in one string: $*
echo \$\@与\$\*基本没区别，在输入参数中含有空格时有用/区别
echo All params in one string: $@
echo \$\$表示当前进程号
echo Current pid: $$
echo \$!表示后台运行的最后一个进程的ID
echo Last pid in backend: $!
echo \$?表示最后的命令的退出的返回值
echo Return value of last command: $?

echo
echo 运算符
echo 用expr时，+两边留空格
expr_var=`expr 2 + 2`
echo expr_var=$expr_var
echo 用方括号进行计算
square_var=$[2+2]
echo square_var=$square_var
echo 用圆括号进行计算
round_var=$((2+2))
echo round_var=$round_var
echo 关系运算符只支持数字，不支持字符串，除非字符串的值是数字
a=10
b=20
printf %s -eq:\ 
if [ $a -eq $b ]
then echo True
else echo False
fi

printf %s -ne:\ 
if [ $a -ne $b ]
then echo True
else echo False
fi

printf %s -gt:\ 
if [ $a -gt $b ]
then echo True
else echo False
fi

printf %s -lt:\ 
if [ $a -lt $b ]
then echo True
else echo False
fi

printf %s -ge:\ 
if [ $a -ge $b ]
then echo True
else echo False
fi

printf %s -le:\ 
if [ $a -le $b ]
then echo True
else echo False
fi

echo 字符串运算符

printf %s =:\ 
if [ $a = $b ]
then echo True
else echo False
fi

printf %s !=:\ 
if [ $a != $b ]
then echo True
else echo False
fi

printf %s -z（检测长度是否为0）:\ 
if [ -z $a ]
then echo True
else echo False
fi

printf %s -n（检测长度是否不为0）:\ 
if [ -n $a ]
then echo True
else echo False
fi

printf %s \$（检测是否不为空）:\ 
if [ $a ]
then echo True
else echo False
fi

echo 布尔运算符
printf %s !（必须不留空格）:\ 
if [ !false ]
then echo True
else echo False
fi
printf %s -o（or）:\ 
if [ 10 -gt 20 -o 20 -gt 10 ]
then echo True
else echo False
fi
printf %s -a（and）:\ 
if [ 10 -gt 20 -a 20 -gt 10 ]
then echo True
else echo False
fi

echo 逻辑运算符
printf %s \&\&（AND）:\ 
if [[ 10 -gt 20 && 20 -gt 10 ]]
then echo True
else echo False
fi
printf %s \|\|（OR）:\ 
if [[ 10 -gt 20 || 20 -gt 10 ]]
then echo True
else echo False
fi

echo 文件运算符
echo '-b file ：检测文件是否是块设备文件，如果是，则返回 true。 [ -b $file ] 返回 false。'
echo '-c file ：检测文件是否是字符设备文件，如果是，则返回 true。 [ -c $file ] 返回 false。'
echo '-d file ：检测文件是否是目录，如果是，则返回 true。 [ -d $file ] 返回 false。'
echo '-f file ：检测文件是否是普通文件（既不是目录，也不是设备文件），如果是，则返回 true。 [ -f $file ] 返回 true。'
echo '-g file ：检测文件是否设置了 SGID 位，如果是，则返回 true。 [ -g $file ] 返回 false。'
echo '-k file ：检测文件是否设置了粘着位(Sticky Bit)，如果是，则返回 true。 [ -k $file ] 返回 false。'
echo '-p file ：检测文件是否是有名管道，如果是，则返回 true。 [ -p $file ] 返回 false。'
echo '-u file ：检测文件是否设置了 SUID 位，如果是，则返回 true。 [ -u $file ] 返回 false。'
echo '-r file ：检测文件是否可读，如果是，则返回 true。 [ -r $file ] 返回 true。'
echo '-w file ：检测文件是否可写，如果是，则返回 true。 [ -w $file ] 返回 true。'
echo '-x file ：检测文件是否可执行，如果是，则返回 true。 [ -x $file ] 返回 true。'
echo '-s file ：检测文件是否为空（文件大小是否大于0），不为空返回 true。 [ -s $file ] 返回 true。'
echo '-e file ：检测文件（包括目录）是否存在，如果是，则返回 true。 [ -e $file ] 返回 true。'

echo 
echo 命令替换
echo ls ./: `ls ./`

echo
echo printf输出
printf "%s %d\n" 这是一个整数 10
printf "%s %s\n" 这是一个字符串 string
printf "%s %c\n" 这是一个字符 A
printf "%s %f\n" 这是一个浮点数 3.141592653589
printf "%s %10d[end]\n" 表示输出10位右对齐 10
printf "%s %-10d[end]\n" 表示输出10位左对齐 10
printf "%s %10.2f[end]\n" 格式化浮点数（宽度为10，保留两位小数，右对齐） 3.14159265
printf "%s %-10.2f[end]\n" 格式化浮点数（宽度为10，保留两位小数，左对齐） 3.14159265

echo 
echo 流程控制
echo if...else
if false
then echo 'if condition'
elif false
then echo 'elif condition'
else echo 'else condition'
fi
echo 'for'
for file in `ls ./`
do
echo file=$file
done
echo 'while'
sum=0
i=0
while [ $i -le 10 ]
do
sum=$((sum+i))
i=$((i+1))
done
echo sum=$sum

echo 
echo 输出重定向
ls ./ > /dev/null
echo 输出+错误重定向
ls ./ >> /dev/null 2>&1